package org.shuma.goods.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.shuma.goods.common.ErrorCode;
import org.shuma.goods.domain.entity.Orders;
import org.shuma.goods.exception.BusinessException;
import org.shuma.goods.mapper.OrdersMapper;
import org.shuma.goods.service.OrdersService;
import org.springframework.stereotype.Service;

import java.text.SimpleDateFormat;
import java.time.LocalDate;
import java.util.Comparator;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
* @author taoha
* @description 针对表【orders】的数据库操作Service实现
* @createDate 2024-06-18 08:33:33
*/
@Service
public class OrdersServiceImpl extends ServiceImpl<OrdersMapper, Orders>
    implements OrdersService{
    @Override
    public Map<String,Long> getProductTop(LocalDate startLocalDate,LocalDate endLocalDate) {

        //获取指定时间范围内的数据记录
        List<Orders> orderList = getOrders(startLocalDate, endLocalDate);
        if(orderList == null){
            throw new BusinessException(ErrorCode.NULL_ERROR);
        }
        // 使用 Stream API 将订单按照商品类型分组并计算总数量
        Map<String, Long> productTypeToCountMap = orderList.stream()
                .collect(Collectors.groupingBy(
                        Orders::getProductType,            // 分组依据：商品类型
                        Collectors.counting()             // 收集器：计算每种商品类型的总数量
                ));
        // 对 Map 按商品数量倒序排序并只保留前20条数据
        Map<String, Long> sortedAndLimitedMap = productTypeToCountMap
                .entrySet()
                .stream()
                .sorted(Map.Entry.<String, Long>comparingByValue().reversed()) // 按值倒序排序
                .limit(20) // 只保留前20条数据
                .collect(Collectors.toMap(
                        Map.Entry::getKey, // 保持键值对
                        Map.Entry::getValue,
                        (e1, e2) -> e1, // 处理值冲突的合并函数
                        LinkedHashMap::new // 使用 LinkedHashMap 保持顺序
                ));

        return sortedAndLimitedMap;


    }

    /**
     * 获取指定时间范围内的数据记录
     * @param startLocalDate
     * @param endLocalDate
     * @return
     */
    private List<Orders> getOrders(LocalDate startLocalDate, LocalDate endLocalDate) {
        QueryWrapper<Orders> queryWrapper = new QueryWrapper<>();
        queryWrapper.ge("product_buy_time", startLocalDate);
        queryWrapper.le("product_buy_time", endLocalDate);
        List<Orders> orderList = this.list(queryWrapper);
        return orderList;
    }

    @Override
    public Map<String, Long> getExchange(LocalDate startLocalDate,LocalDate endLocalDate) {

        //获取指定时间范围内的数据记录
        List<Orders> orderList = getOrders(startLocalDate, endLocalDate);
        if(orderList == null){
            throw new BusinessException(ErrorCode.NULL_ERROR);
        }
        // 将订单按照商品兑换方式分组并计算总数量
        Map<String, Long> productExchangeTypeToCountMap = orderList.stream()
                .collect(Collectors.groupingBy(
                        Orders::getProductExchangeType, // 分组依据：商品兑换方式
                        Collectors.counting()  // 收集器：计算每种商品兑换方式的总数量
                ));

        return productExchangeTypeToCountMap;
    }

    @Override
    public Map<String, Long> getSalesVolume(LocalDate startLocalDate,LocalDate endLocalDate) {

        //获取指定时间范围内的数据记录
        List<Orders> orderList = getOrders(startLocalDate, endLocalDate);
        if(orderList == null){
            throw new BusinessException(ErrorCode.NULL_ERROR);
        }
        // 将订单按照购买日期分组，按照日期从小到大排序，并计算每组总数量
        Map<String, Long> dateToCountMap = orderList.stream()
                .collect(Collectors.groupingBy(
                        order -> new SimpleDateFormat("yyyy-MM-dd").format(order.getProductBuyTime()), // 分组依据：购买日期
                        Collectors.counting()  // 收集器：计算每个日期的订单总数量
                ))
                .entrySet()
                .stream()
                .sorted(Map.Entry.comparingByKey(Comparator.naturalOrder())) // 按日期从小到大排序
                .collect(Collectors.toMap(
                        Map.Entry::getKey,
                        Map.Entry::getValue,
                        (e1, e2) -> e1,
                        LinkedHashMap::new // 使用 LinkedHashMap 保证顺序
                ));


        return dateToCountMap;
    }


}




